home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $PROJECT: GoldED Phrase-Completion API-Client
- **
- ** $VER: PhraseCompletion.c 1.4 (27.04.96)
- **
- ** by
- **
- ** Stefan Ruppert , Windthorststrasse 5 , 65439 Floersheim , GERMANY
- **
- ** (C) Copyright 1996
- ** All Rights Reserved !
- **
- ** $HISTORY:
- **
- ** 27.04.96 : 001.004 : completion didn't worded, if word was at the beginning of a line (fixed)
- ** 14.04.96 : 001.003 : now uses WHITESPACES arg to get the word to expand
- ** 24.02.96 : 001.002 : searches now in the line of the cursor
- ** 09.02.96 : 001.001 : separated in a own program
- **
- */
-
- /*FS*//* --------------------------- version defines ---------------------------- */
-
- /* $STARTDEFINE: "BumpRev defines"*/
- #define VERSION 1
- #define REVISION 4
- #define DATE "27.4.96"
- #define VERS "PhraseCompletion 1.4"
- #define VSTRING "PhraseCompletion 1.4 (27.4.96)\r\n"
- #define VERSTAG "\0$VER: PhraseCompletion 1.4 (27.4.96)"
- #define NAME "PhraseCompletion"
- #define PROJECTNAME "PhraseCompletion: "
-
- /* $ENDDEFINE: */
- /*FE*/
-
- /*FS*//* ------------------------------- include -------------------------------- */
-
- #define __USE_SYSBASE
-
- #include <string.h>
- #include <ctype.h>
-
- #include <exec/types.h>
- #include <exec/memory.h>
-
- #include <dos/dos.h>
-
- #include <rexx/errors.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/utility.h>
- #include <proto/rexxsyslib.h>
-
- #include <clib/alib_protos.h>
- #include <clib/alib_stdio_protos.h>
-
- #include "golded:api/include/golded.h"
-
- #include "debug.h"
- #include "register.h"
- /*FE*/
-
- /*FS*//* ------------------------------- AutoDoc -------------------------------- */
-
- /*GB*** GoldED-API/PharseCompletion ******************************************
-
- $VER: PharseCompletion.doc 1.4 (27.4.96)
-
- NAME
- PhraseCompletion
-
- VERSION
- 1.4
-
- DESCRIPTION
- Just run GoldED and load this as an API-Client ! Then you have the
- following new ARexx command :
-
- TEMPLATE
- PHRASECOMPLETION WHITESPACES,MAX/N,CASE/S,BACKWARD/S,ALL/S
-
- FORMAT
- PHRASECOMPLETION [[WHITESPACES] whitespace-characters] [[MAX] number]
- [CASE] [BACKWARD] [ALL]
-
- DESCRIPTION
- The PHRASECOMPLETION ARexx command provides you a new phrase
- completion method. It extracts the actual word-phrase (before cursor)
- and tries to complete this phrase. This is done by searching in the
- buffers for a word beginning with this extracted phrase. The first
- found is displayed in the buffer. If there are more than one words
- matching the phrase, you can step through all found words by just
- using this command again with same cursor position. If the last word
- is reached a ERROR_NO_MORE_ENTRIES error code is returned and then it
- starts again with the first word.
-
- INPUTS
- WHITESPACES -- a string, which represent the characters to use as
- whitespaces. Default is " \t".
-
- MAX -- maximal number of matching words. Default is ~0.
-
- CASE -- don't ignore case-sensetive. Default is ignore.
-
- BACKWARD -- normaly the buffer is first searched from the actual
- line to the beginnig and then from actual line to the end of
- the buffer. This argument swaps the search direction.
-
- ALL -- searchs in all opened buffers
-
- RESULTS
- the command returns RC_OK, if it could complete the pharse. RC_WARN
- if not !
-
- SPECIAL REQUIREMENTS
- Needs GoldED 3.x to run.
-
- AVAILABILITY
- ftp://wuarchive.wustl.edu/pub/aminet/text/edit/GED-PhrCmp1.4.lha
- And all other Aminet sites
-
- AUTHOR
- Stefan Ruppert
- Windthorststrasse 5
- 65439 Floersheim
- Germany
-
- Internet:
- ruppert@informatik.fh-wiesbaden.de
- ruppert@goofy.zdv.uni-mainz.de
- http://www.uni-mainz.de/~ruppert
-
- SEE ALSO
- Emacs, GoldED/API
-
- *****************************************************************************/
- /*FE*/
-
- /*FS*//* ------------------------------- defines -------------------------------- */
-
- #define PUDDLE_SIZE 4096
- #define BUFFER_LEN 512
-
- #define PHRASECOMP_ARGS "WHITESPACES,MAX/N,CASE/S,BACKWARD/S,ALL/S"
-
- #define MAX_PARAMETER 6
-
- #define EOS '\0'
-
- #define USETAG(tag,check) ((check) ? (tag) : TAG_IGNORE)
-
- /*FE*/
-
- /*FS*//* ----------------------------- structures ------------------------------- */
-
- struct RexxCommands
- {
- STRPTR rxc_Command;
- LONG (*rxc_Handler) (struct GlobalData *,struct APIMessage *);
- STRPTR rxc_Template;
- };
-
- struct GlobalData
- {
- struct Library *gd_SysBase;
- struct Library *gd_DOSBase;
- struct Library *gd_UtilityBase;
- struct Library *gd_RexxSysBase;
-
- APTR gd_Pool;
- APTR gd_FoundPool;
-
- struct MsgPort *gd_ApiPort;
- struct MsgPort *gd_RexxPort;
-
- STRPTR gd_GoldEDHost;
-
- ULONG gd_Result;
- LONG gd_Found;
-
- struct List gd_FoundList;
- struct Node *gd_LastFound;
-
- ULONG gd_Para[MAX_PARAMETER];
-
- ULONG gd_Len;
- ULONG gd_Max;
- UBYTE gd_Buffer[BUFFER_LEN];
- UBYTE gd_Name[BUFFER_LEN];
- UBYTE gd_LastName[BUFFER_LEN];
-
- struct APIModifyRequest gd_Modify;
- };
- /*FE*/
-
- /*FS*//* ------------------------------ prototypes ------------------------------ */
-
- void search_command(struct GlobalData *gd,struct APIMessage *msg);
-
- LONG RexxCmd_PhraseComp(struct GlobalData *gd,struct APIMessage *msg);
-
- BOOL send_rexxcommand(struct GlobalData *gd,STRPTR cmd);
- BOOL alloc_name(struct GlobalData *gd,STRPTR name,LONG len);
-
- RegCall void *AsmCreatePool(REGD0 ULONG ,REGD1 ULONG ,REGD2 ULONG ,REGA6 struct Library *);
- RegCall void AsmDeletePool(REGA0 APTR ,REGA6 struct Library *);
- RegCall void *AsmAllocPooled(REGA0 APTR ,REGD0 ULONG ,REGA6 struct Library *);
- RegCall void AsmFreePooled(REGA0 APTR ,REGA1 APTR ,REGD0 ULONG ,REGA6 struct Library *);
-
- /*FE*/
-
- /*FS*//* -------------------------- static data items --------------------------- */
-
- static const STRPTR version = VERSTAG;
- static const STRPTR prgname = NAME;
-
- static struct RexxCommands rexxcmd[] = {
- {"PHRASECOMPLETION",RexxCmd_PhraseComp,PHRASECOMP_ARGS},
- {NULL}};
-
- static struct TagItem apitags[] = {
- {API_Client_Name ,(ULONG) NAME},
- {API_Client_Copyright ,(ULONG) "©1996 Stefan Ruppert"},
- {API_Client_Purpose ,(ULONG) VERS "\n\nPhrase completion\nthrough all buffers"},
- {API_Client_Template ,(ULONG) "PHRASECOMPLETION " PHRASECOMP_ARGS},
- {TAG_DONE,0}};
- /*FE*/
-
- /*FS*//* ------------------------- template definition -------------------------- */
-
- #define template "HOST/K/A"
-
- enum {
- ARG_HOST,
- ARG_MAX};
- /*FE*/
-
- /* --------------------------- main entry point --------------------------- */
-
- /*FS*/GetA4 int main(void)
- {
- struct Library *SysBase = *((struct Library **) 4L);
- struct Library *DOSBase;
- struct RDArgs *args;
- LONG para[ARG_MAX];
- STRPTR obj = prgname;
- LONG rc = RETURN_OK;
-
- LONG i;
-
- /* clear args buffer */
- for(i = 0 ; i < ARG_MAX ; i++)
- para[i] = 0;
-
- if((DOSBase = OpenLibrary("dos.library",37)) != NULL)
- {
- LONG err = 0;
-
- if((args = ReadArgs(template,para,NULL)) != NULL)
- {
- APTR pool;
-
- if((pool = AsmCreatePool(MEMF_CLEAR | MEMF_ANY, PUDDLE_SIZE, PUDDLE_SIZE,SysBase)) != NULL)
- {
- struct GlobalData *gd;
-
- DB(("golded host : %s\n",para[ARG_HOST]));
- if((gd = AsmAllocPooled(pool,sizeof(struct GlobalData),SysBase)) != NULL)
- {
- gd->gd_Pool = pool;
-
- gd->gd_SysBase = SysBase;
- gd->gd_DOSBase = DOSBase;
-
- gd->gd_UtilityBase = OpenLibrary("utility.library",37);
- gd->gd_RexxSysBase = OpenLibrary("rexxsyslib.library",36);
-
- NewList(&gd->gd_FoundList);
-
- if(gd->gd_UtilityBase != NULL && gd->gd_RexxSysBase != NULL)
- {
- if((gd->gd_ApiPort = CreateMsgPort()))
- {
- if((gd->gd_RexxPort = CreateMsgPort()))
- {
- gd->gd_GoldEDHost = (STRPTR) para[ARG_HOST];
-
- sprintf(gd->gd_Buffer,"API PORT=%ld CLASS=%ld",
- gd->gd_ApiPort,
- API_CLASS_ROOT | API_CLASS_REXX);
-
- if(send_rexxcommand(gd,gd->gd_Buffer) && gd->gd_Result == RC_OK)
- {
- struct APIMessage *apimsg;
- struct APIMessage *msg;
-
- BOOL active = TRUE;
-
- DB(("xrefapi active !\n"));
-
- do
- {
- WaitPort(gd->gd_ApiPort);
-
- while((apimsg = (struct APIMessage *) GetMsg(gd->gd_ApiPort)))
- {
- for(msg = apimsg ; msg ; msg = msg->api_Next)
- {
- if(msg->api_State == API_STATE_NOTIFY)
- {
- switch(msg->api_Class)
- {
- case API_CLASS_ROOT:
- switch(msg->api_Action)
- {
- case API_ACTION_DIE:
- active = FALSE;
- break;
- case API_ACTION_INTRODUCE:
- msg->api_Data = apitags;
- break;
- }
- break;
- case API_CLASS_REXX:
- switch(msg->api_Action)
- {
- case API_ACTION_COMMAND:
- search_command(gd,msg);
- break;
- default:
- msg->api_Error = API_ERROR_UNKNOWN;
- }
- break;
- default:
- msg->api_Error = API_ERROR_UNKNOWN;
- }
- }
- }
-
- ReplyMsg((struct Message *) apimsg);
- }
- } while(active);
- SetIoErr(0);
- }
- DeleteMsgPort(gd->gd_RexxPort);
- }
- DeleteMsgPort(gd->gd_ApiPort);
- }
-
- if(gd->gd_FoundPool != NULL)
- AsmDeletePool(gd->gd_FoundPool,SysBase);
- }
-
- CloseLibrary(gd->gd_RexxSysBase);
- CloseLibrary(gd->gd_UtilityBase);
- }
-
- AsmDeletePool(pool,SysBase);
- }
- FreeArgs(args);
- }
-
- if(err == 0)
- err = IoErr();
-
- if(err != 0)
- {
- PrintFault(err,obj);
- rc = RETURN_ERROR;
- }
-
- CloseLibrary(DOSBase);
- }
-
- return rc;
- }
- #define SysBase gd->gd_SysBase
- #define DOSBase gd->gd_DOSBase
- #define UtilityBase gd->gd_UtilityBase
- #define RexxSysBase gd->gd_RexxSysBase
- /*FE*/
-
- /* -------------------------- find rexx command --------------------------- */
-
- /*FS*/ void search_command(struct GlobalData *gd,struct APIMessage *msg)
- {
- struct APIRexxNotify *notify = (struct APIRexxNotify *) msg->api_Data;
- struct RexxCommands *rxcmd = rexxcmd;
- LONG len;
-
- notify->arn_RC = RC_WARN;
-
- while(rxcmd->rxc_Command)
- {
- len = strlen(rxcmd->rxc_Command);
-
- if(!strncmp(notify->arn_Command,rxcmd->rxc_Command,len))
- {
- struct RDArgs *rdargs;
- struct RDArgs *args;
- LONG i;
-
- msg->api_State = API_STATE_CONSUMED;
-
- strncpy(gd->gd_Buffer,¬ify->arn_Command[len],BUFFER_LEN);
- strncat(gd->gd_Buffer,"\n",BUFFER_LEN);
-
- if(rdargs = (struct RDArgs *) AllocDosObject(DOS_RDARGS,NULL))
- {
- rdargs->RDA_Source.CS_Buffer = gd->gd_Buffer;
- rdargs->RDA_Source.CS_Length = strlen(gd->gd_Buffer);
-
- for(i=0 ; i < MAX_PARAMETER ; i++)
- gd->gd_Para[i]=0;
-
- DB(("rdargs at : %lx\n",rdargs));
-
- if((args = ReadArgs(rxcmd->rxc_Template,(LONG *) gd->gd_Para,rdargs)))
- {
- DB(("args at %lx\n",args));
-
- notify->arn_RC = rxcmd->rxc_Handler(gd,msg);
-
- FreeArgs(args);
- }
- FreeDosObject(DOS_RDARGS , rdargs);
- }
- }
- rxcmd++;
- }
-
- if(notify->arn_RC != RC_OK)
- {
- Fault(IoErr(),NAME,gd->gd_Buffer,BUFFER_LEN);
- notify->arn_CommandError = gd->gd_Buffer;
- }
- }
- /*FE*/
-
- /* ---------------------------- rexx commands ----------------------------- */
-
- /*FS*//*"LONG RexxCmd_PhraseComp(struct GlobalData *gd,struct APIMessage *msg)"*/
- struct IntArgs
- {
- STRPTR ia_WhiteSpaces;
- LONG *ia_Max;
- LONG ia_Case;
- LONG ia_Backward;
- LONG ia_All;
- };
- /*FS*/ void match_expand(struct GlobalData *gd,struct IntArgs *args,struct LineNode *ln)
- {
- STRPTR name;
- STRPTR ptr;
- STRPTR end;
- LONG len;
-
- ptr = ln->Text;
- end = ptr + ln->Len;
-
- if(args->ia_Case)
- {
- do
- {
- while(ptr < end && strchr(args->ia_WhiteSpaces,*ptr) != NULL)
- ptr++;
-
- name = ptr;
- while(ptr < end && strchr(args->ia_WhiteSpaces,*ptr) == NULL)
- ptr++;
-
- len = ptr - name;
- if(len > gd->gd_Len)
- {
- if(!strncmp(name,gd->gd_Buffer,gd->gd_Len))
- {
- alloc_name(gd,name,len);
- if(--gd->gd_Max == 0)
- break;
- }
- }
- } while(ptr < end);
- } else
- {
- do
- {
- while(ptr < end && strchr(args->ia_WhiteSpaces,*ptr) != NULL)
- ptr++;
-
- name = ptr;
- while(ptr < end && strchr(args->ia_WhiteSpaces,*ptr) == NULL)
- ptr++;
-
- len = ptr - name;
- if(len > gd->gd_Len)
- {
- if(!Strnicmp(name,gd->gd_Buffer,gd->gd_Len))
- {
- alloc_name(gd,name,len);
- if(--gd->gd_Max == 0)
- break;
- }
- }
- } while(ptr < end);
- }
-
- if(ln->Fold != NULL)
- {
- struct LineNode *end;
- len = ln->Fold->Lines;
- ln = ln->Fold->TextNodes;
-
- end = ln + len;
- while(ln < end && gd->gd_Max > 0)
- {
- match_expand(gd,args,ln++);
- }
- }
-
- return;
- }
- /*FE*/
-
- LONG RexxCmd_PhraseComp(struct GlobalData *gd,struct APIMessage *msg)
- {
- struct EditConfig *ec = msg->api_Config;
- struct LineNode *ln;
- struct IntArgs *args = (struct IntArgs *) gd->gd_Para;
-
- UWORD column;
- STRPTR wrd;
- STRPTR buf;
- LONG retval = RC_WARN;
-
- gd->gd_Max = ~0;
- if(args->ia_Max != NULL)
- gd->gd_Max = *args->ia_Max;
-
- column = ec->Column;
- buf = ec->CurrentBuffer;
- wrd = gd->gd_Buffer;
-
- if(column > 0)
- {
- STRPTR found = NULL;
- STRPTR end = buf + column;
- STRPTR begin = end - 1;
- LONG foundlen;
- LONG len;
-
- while(begin >= buf && strchr(args->ia_WhiteSpaces,*begin) == NULL)
- begin--;
- begin++;
- column -= (end - begin);
-
- len = end - begin;
-
- if(len == 0)
- SetIoErr(ERROR_REQUIRED_ARG_MISSING);
- else
- {
- movmem(begin,wrd,len);
- wrd[len] = 0;
- gd->gd_Len = len;
-
- DB(("expand : %s\n",wrd));
-
- if(!IsListEmpty(&gd->gd_FoundList) && gd->gd_LastName[0] != '\0' &&
- !strncmp(gd->gd_LastName,wrd,strlen(gd->gd_LastName)))
- {
- struct Node *node = gd->gd_LastFound;
-
- DB(("Get Next word : %lx\n",node));
- if(node != NULL)
- {
- node = node->ln_Succ;
- if(node->ln_Succ != NULL)
- gd->gd_LastFound = node;
- else
- gd->gd_LastFound = NULL;
- } else
- gd->gd_LastFound = gd->gd_FoundList.lh_Head;
-
- if(gd->gd_LastFound != NULL)
- {
- found = gd->gd_LastFound->ln_Name;
- foundlen = strlen(found);
- } else
- SetIoErr(ERROR_NO_MORE_ENTRIES);
- } else
- {
- LONG try = 2;
-
- strcpy(gd->gd_LastName,wrd);
- if(gd->gd_FoundPool != NULL)
- AsmDeletePool(gd->gd_FoundPool,SysBase);
- NewList(&gd->gd_FoundList);
- gd->gd_LastFound = NULL;
- gd->gd_FoundPool = AsmCreatePool(MEMF_ANY | MEMF_CLEAR,PUDDLE_SIZE,PUDDLE_SIZE,SysBase);
-
- if(args->ia_WhiteSpaces == NULL)
- args->ia_WhiteSpaces = " \t";
-
- while(try > 0 && gd->gd_Max > 0)
- {
- try--;
- if(args->ia_Backward)
- {
- struct LineNode *end = ec->TextNodes + ec->Lines;
- ln = &ec->TextNodes[ec->Line]+1;
- while(ln < end && gd->gd_Max > 0)
- match_expand(gd,args,ln++);
- } else
- {
- ULONG len;
-
- ln = &ec->TextNodes[ec->Line];
- /* cut current line to the cursor pos */
- len = ln->Len;
- ln->Len = ec->Column-1;
- match_expand(gd,args,ln);
- ln->Len = len;
- ln--;
-
- while(ln >= ec->TextNodes && gd->gd_Max > 0)
- match_expand(gd,args,ln--);
- }
- args->ia_Backward = !args->ia_Backward;
- }
-
- if(args->ia_All && gd->gd_Max > 0)
- {
- struct EditConfig *first = ec;
-
- while(first->Node.ln_Pred != NULL)
- first = (struct EditConfig *) first->Node.ln_Pred;
-
- first = (struct EditConfig *) first->Node.ln_Succ;
-
- while(first->Node.ln_Succ != NULL && gd->gd_Max > 0)
- {
- struct LineNode *end = first->TextNodes + first->Lines;
- DB(("name : %s\n",first->Name));
-
- if(first != ec)
- {
- ln = first->TextNodes;
- while(ln < end && gd->gd_Max > 0)
- match_expand(gd,args,ln++);
- }
-
- first = (struct EditConfig *) first->Node.ln_Succ;
- }
-
- }
-
- if(gd->gd_FoundList.lh_Head->ln_Succ != NULL)
- {
- struct Node *node = gd->gd_FoundList.lh_Head;
-
- #if 0
- if(args->ia_Select)
- node = select_node(gd,&gd->gd_FoundList,msg->api_Global->F_ScrnName);
- #endif
-
- if(node != NULL)
- {
- gd->gd_LastFound = node;
- found = node->ln_Name;
- foundlen = strlen(found);
- } else
- SetIoErr(ERROR_OBJECT_NOT_FOUND);
- } else
- SetIoErr(ERROR_OBJECT_NOT_FOUND);
- }
-
- DB(("found = \"%s\" , len : %ld\n",found,foundlen));
- if(found != NULL && foundlen > 0)
- {
- strncpy(gd->gd_LastName,found,foundlen);
- gd->gd_LastName[foundlen] = '\0';
-
- strncpy(gd->gd_Buffer,ec->CurrentBuffer,column);
- strncpy(&gd->gd_Buffer[column],found,foundlen);
- strcpy(&gd->gd_Buffer[column + foundlen],ec->CurrentBuffer + ec->Column);
- gd->gd_Modify.mr_Next = NULL;
- gd->gd_Modify.mr_Line = ec->Line;
- gd->gd_Modify.mr_Column = column + foundlen;
- gd->gd_Modify.mr_Data = gd->gd_Buffer;
- gd->gd_Modify.mr_Size = column + foundlen + (ec->CurrentLen - ec->Column);
-
- msg->api_Modify = &gd->gd_Modify;
-
- msg->api_Refresh |= API_REFRESH_LINE;
-
- retval = RC_OK;
- }
- }
- }
-
- return retval;
- }
- /*FE*/
-
- /* -------------------------- support functions --------------------------- */
-
- /*FS*/BOOL send_rexxcommand(struct GlobalData *gd,STRPTR cmd)
- {
- struct MsgPort *rexxport;
-
- Forbid();
-
- if((rexxport = FindPort(gd->gd_GoldEDHost)))
- {
- struct RexxMsg *rxmsg;
- struct RexxMsg *answer;
-
- if((rxmsg = CreateRexxMsg(gd->gd_RexxPort, NULL, NULL)) != NULL)
- {
- if((rxmsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) != NULL)
- {
- rxmsg->rm_Action = RXCOMM | RXFF_RESULT;
-
- PutMsg(rexxport, &rxmsg->rm_Node);
-
- do
- {
- WaitPort(gd->gd_RexxPort);
-
- if((answer = (struct RexxMsg *) GetMsg(gd->gd_RexxPort)))
- gd->gd_Result = answer->rm_Result1;
-
- } while (!answer);
-
- Permit();
-
- if(answer->rm_Result1 == RC_OK)
- {
- if(answer->rm_Result2)
- {
- if(gd->gd_Buffer)
- strcpy(gd->gd_Buffer, (char *)answer->rm_Result2);
-
- DeleteArgstring((char *)answer->rm_Result2);
- }
- }
-
- DeleteArgstring((char *)ARG0(answer));
-
- DeleteRexxMsg(answer);
-
- return(TRUE);
- }
- }
- }
-
- Permit();
-
- return(FALSE);
- }
- /*FE*/
- /*FS*/ BOOL alloc_name(struct GlobalData *gd,STRPTR name,LONG len)
- {
- struct Node *node;
- BOOL rc = FALSE;
-
- for(node = gd->gd_FoundList.lh_Head ; node->ln_Succ != NULL ; node = node->ln_Succ)
- if(node->ln_Type == len && !strncmp(node->ln_Name,name,len))
- break;
-
- if(node->ln_Succ == NULL)
- if((node = AsmAllocPooled(gd->gd_FoundPool,sizeof(struct Node) + len + 1,SysBase)) != NULL)
- {
- node->ln_Name = (STRPTR) (node + 1);
- node->ln_Type = len;
-
- strncpy(node->ln_Name,name,len);
-
- AddTail(&gd->gd_FoundList,node);
-
- rc = TRUE;
- DB(("allocated : %s\n",node->ln_Name));
- }
-
-
- return rc;
- }
- /*FE*/
-
-